package storage.data;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

import org.mapdb.DB;
import org.mapdb.Serializer;

import core.engine.systemDBEngine;
import logging.transaction.TransactionLogger;
import sql.constraints.ConstraintType;
import sql.constraints.TableConstraint;
import storage.StorageException; // 添加对 StorageException 的导入

public class DataManager {

    /**
     * 插入数据到表数据文件。
     * @param dbName 数据库名称
     * @param tableName 表名
     * @param data 数据内容，每个字段为一个字符串
     * @param schemaList 表结构信息,每个字段包含 [字段名, 数据类型, 字节长度]
     * @return 1 表示成功，0 表示失败
     */
    @SuppressWarnings("unchecked")
    public static int insertData(String dbName, String tableName, List<String> data, List<String[]> schemaList) {
        // 1. 从TransactionLogger获取DB实例
        DB db = TransactionLogger.getInstance().getCurrentTransactionDB();

        // 2. 检查事务状态和数据库上下文
        if (db == null) {
            System.err.println("错误: insertData 操作需要在活动的事务中执行。");
            // 对于更健壮的错误处理，这里应该抛出自定义异常，例如:
            // throw new IllegalStateException("insertData 操作需要在活动的事务中执行。");
            return 0; 
        }
        String activeTransactionDbName = TransactionLogger.getInstance().getTransactionDatabaseName();
        if (activeTransactionDbName == null || !activeTransactionDbName.equals(dbName)) {
            System.err.println("错误: insertData 操作的数据库 '" + dbName + "' 与当前活动事务的数据库 '" + activeTransactionDbName + "' 不符。");
            // 对于更健壮的错误处理，这里应该抛出自定义异常，例如:
            // throw new IllegalStateException("数据库上下文与当前活动事务不匹配。");
            return 0;
        }
        if (db.isClosed()) { // 额外的健全性检查
            System.err.println("错误: 与当前事务关联的数据库实例已关闭。事务将被回滚。");
            // 如果db已关闭，这通常意味着一个严重的问题，或者事务已经被外部因素无效化。
            // 通知TransactionLogger尝试回滚并清理其状态。
            TransactionLogger.getInstance().rollbackTransaction(); 
            return 0;
        }

        try {
            // 3. 参数验证 (保留原有逻辑, 但移除对dbName的单独null检查，因为它已通过事务上下文间接验证)
            // if (dbName == null || tableName == null || data == null || schemaList == null) { // dbName检查已移除
            if (tableName == null || data == null || schemaList == null) {
                System.err.println("❌ 插入数据参数不完整 (表名、数据或结构列表为空)");
                return 0;
            }

            if (data.size() != schemaList.size()) {
                System.err.println("❌ 字段数量不匹配，应有 " + schemaList.size() + " 个字段，实际收到 " + data.size());
                return 0;
            }

            // 4. 检查表是否存在
            Map<String, Object> tableInfo = (Map<String, Object>) db
                .hashMap("TableInfo")
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("tables", new HashMap<String, Object>());

            List<String> tablesList = tableInfo != null ?
                (List<String>) tableInfo.getOrDefault("tablesList", new ArrayList<String>()) :
                    new ArrayList<>();

            if (!tablesList.contains(tableName)) {
                System.err.println("❌ 表 [" + tableName + "] 不存在");
                return 0;
            }

            // 5. 获取表列信息，用于约束检查 (现在主要用于类型校验和列名到索引的映射)
            List<Map<String, Object>> columnsInfo = (List<Map<String, Object>>) db
                .hashMap("columns_" + tableName)
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("metadata", new ArrayList<Map<String, Object>>());

            if (columnsInfo.isEmpty()) {
                System.err.println("❌ 表 [" + tableName + "] 的列信息为空");
                return 0;
            }

            // 建立列名到列信息的映射，便于快速查找
            Map<String, Map<String, Object>> columnMap = new HashMap<>();
            for (Map<String, Object> colInfo : columnsInfo) {
                String name = (String)colInfo.get("name");
                if (name != null) {
                    columnMap.put(name, colInfo);
                }
            }

            // 6. 创建列名到索引的映射
            Map<String, Integer> columnIndexMap = new HashMap<>();
            for (int i = 0; i < schemaList.size(); i++) {
                String[] column = schemaList.get(i);
                if (column != null && column.length > 0 && column[0] != null) {
                    columnIndexMap.put(column[0], i);
                }
            }

            // 7. 处理数据并进行校验 (类型、长度等)
            List<String> processedData = new ArrayList<>(data); // 创建数据的副本进行处理
            for (int i = 0; i < processedData.size(); i++) {
                String value = processedData.get(i);
                String[] columnDef = schemaList.get(i);

                if (columnDef == null || columnDef.length < 3) {
                    System.err.println("❌ 第 " + (i+1) + " 列定义信息不完整");
                    return 0;
                }

                String columnName = columnDef[0];
                String dataType = columnDef[1];

                // 确保类型和长度值有效
                int maxLength;
                try {
                    maxLength = Integer.parseInt(columnDef[2]);
                } catch (NumberFormatException e) {
                    System.err.println("❌ 列 [" + columnName + "] 的长度定义无效: " + columnDef[2]);
                    return 0;
                }

                // 仅处理原始的 NULL 值，具体的非空检查将由约束模块处理
                if (value == null || value.equalsIgnoreCase("NULL")) {
                    processedData.set(i, ""); // 将SQL NULL统一视为空字符串进行后续处理或类型转换
                    // 但实际的 NOT NULL 约束会在后面检查
                } else if (value.startsWith("'") && value.endsWith("'")) {
                    // 去除引号，仅保留内容
                    value = value.substring(1, value.length() - 1);
                    processedData.set(i, value); // 更新处理后的值
                } else {
                    // 对于非NULL且非引用字符串，保留原样，后续类型转换会处理
                    processedData.set(i, value);
                }

                // 长度校验 (在类型校验之前，确保值不会太长导致后续解析问题)
                if (processedData.get(i).length() > maxLength) {
                    System.err.println("⚠️ 字段 [" + columnName + "] 值超长，已截断前" + maxLength + "字符");
                    processedData.set(i, processedData.get(i).substring(0, maxLength));
                }

                // 类型校验 (在所有预处理之后)
                String currentValue = processedData.get(i);
                // 如果当前值是空字符串（可能来自原始NULL或空输入），并且列本身允许NULL（通过NOT NULL约束判断），则跳过类型校验
                // 但这里我们不能提前知道是否允许NULL，所以类型校验需要能处理空字符串
                String upperDataType = dataType.toUpperCase();
                try {
                    switch (upperDataType) {
                        case "INT":
                        case "INTEGER":
                            if (!currentValue.isEmpty()) {
                                if (!currentValue.matches("-?\\d+")) { // 只有非空时才校验格式
                                    System.err.println("❌ 字段 [" + columnName + "] 类型不匹配，应为 INTEGER，实际值: '" + currentValue + "'");
                                    return 0;
                                }
                                // 对于INT类型，将字符串转换为Long类型存储
                                try {
                                    Long.parseLong(currentValue);
                                } catch (NumberFormatException e) {
                                    System.err.println("❌ 字段 [" + columnName + "] 值转换失败: " + currentValue);
                                    return 0;
                                }
                            }
                            break;
                        case "VARCHAR":
                        case "CHAR":
                        case "TEXT":
                            // 字符串类型无需额外校验，仅长度限制
                            break;
                        case "DATE":
                            if (!currentValue.matches("\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])")) {
                                System.err.println("❌ 字段 [" + columnName + "] 日期格式错误，应为 YYYY-MM-DD");
                                return 0;
                            }
                            break;
                        case "DECIMAL":
                        case "NUMERIC":
                        case "FLOAT":
                        case "DOUBLE":
                            if (!currentValue.matches("-?\\d+(\\.\\d+)?")) {
                                System.err.println("❌ 字段 [" + columnName + "] 类型不匹配，应为 DECIMAL/FLOAT/DOUBLE");
                                return 0;
                            }
                            break;
                        case "BOOLEAN":
                            if (!currentValue.equalsIgnoreCase("true")
                                && !currentValue.equalsIgnoreCase("false")
                                && !currentValue.matches("[01]")) {
                                System.err.println("❌ 字段 [" + columnName + "] 类型不匹配，应为 BOOLEAN (true/false/1/0)");
                                return 0;
                            }
                            // 标准化布尔值格式
                            if (currentValue.equals("1")) {
                                processedData.set(i, "true");
                            } else if (currentValue.equals("0")) {
                                processedData.set(i, "false");
                            }
                            break;
                        case "TIMESTAMP":
                        case "DATETIME":
                            if (!currentValue.matches("\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?")) {
                                System.err.println("❌ 字段 [" + columnName + "] 时间戳格式错误，应为 YYYY-MM-DD [HH:mm[:ss]]");
                                return 0;
                            }
                            break;
                        default:
                            System.out.println("⚠️ 未知字段类型: " + dataType + "，将作为字符串处理");
                            break;
                    }
                } catch (Exception e) {
                    System.err.println("❌ 字段 [" + columnName + "] 值处理失败: " + e.getMessage());
                    return 0;
                }
            }

            // 8. 获取约束信息 (替换旧的 keysInfo 获取)
            List<Map<String, Object>> constraintsMapList = (List<Map<String, Object>>) db
                .hashMap("constraints_" + tableName)
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("metadata", new ArrayList<Map<String, Object>>());

            List<TableConstraint> constraints = new ArrayList<>();
            for (Map<String, Object> constraintMap : constraintsMapList) {
                try {
                    constraints.add(TableConstraint.fromMap(constraintMap));
                } catch (IllegalArgumentException e) {
                    System.err.println("⚠️ 加载约束定义失败: " + constraintMap.get("name") + " - " + e.getMessage());
                    // 可以选择忽略此错误约束或中止操作
                }
            }

            // === DEFAULT约束处理（最小增量） ===
            for (TableConstraint constraint : constraints) {
                if (constraint.getType() == ConstraintType.DEFAULT) {
                    String col = constraint.getColumns().get(0);
                    Integer idx = columnIndexMap.get(col);
                    if (idx != null && (idx >= processedData.size() || processedData.get(idx).isEmpty())) {
                        while (processedData.size() <= idx) processedData.add("");
                        processedData.set(idx, constraint.getDefaultValue());
                    }
                }
            }
            // === END ===

            // 获取当前表数据，用于唯一/主键约束检查
            ConcurrentMap<Long, Object> dataMap = systemDBEngine.getDataStorage(db, tableName);
            if (dataMap == null) {
                System.err.println("❌ 无法获取表 [" + tableName + "] 的数据存储");
                return 0;
            }

            // 9. 执行约束校验 (包括 NOT NULL, UNIQUE, PRIMARY KEY, CHECK, FOREIGN KEY)
            // 首先收集所有列的当前待插入值，映射列名到实际值
            Map<String, String> currentRowValues = new HashMap<>();
            for(int i=0; i<schemaList.size(); i++){
                String colName = schemaList.get(i)[0];
                currentRowValues.put(colName, processedData.get(i)); // 使用 processedData
            }

            for (TableConstraint constraint : constraints) {
                switch (constraint.getType()) {
                    case NOT_NULL:
                        // ... (existing NOT_NULL logic using processedData)
                        for (String colName : constraint.getColumns()) {
                            Integer colIndex = columnIndexMap.get(colName);
                            if (colIndex != null) {
                                if (processedData.get(colIndex).isEmpty()) {
                                    System.err.println("❌ 违反 NOT NULL 约束 [" + constraint.getName() + "] 在列 '" + colName + "'");
                                    throw new StorageException("违反 NOT NULL 约束 [" + constraint.getName() + "] 在列 '" + colName + "'");
                                }
                            }
                        }
                        break;
                    case UNIQUE:
                    case PRIMARY_KEY:
                        // ... (existing UNIQUE/PRIMARY_KEY logic using processedData)
                        List<String> constraintColumnNames = constraint.getColumns();
                        if (constraintColumnNames.isEmpty()) continue;
                        StringBuilder currentValueCombination = new StringBuilder();
                        for (String colName : constraintColumnNames) {
                            Integer colIndex = columnIndexMap.get(colName);
                            if (colIndex != null) {
                                currentValueCombination.append(processedData.get(colIndex)).append("\\0");
                            } else {
                                System.err.println("警告: " + constraint.getType() + " 约束 [" + constraint.getName() + "] 引用了未知列 '" + colName + "'，跳过此列检查");
                            }
                        }
                        String currentKeyStr = currentValueCombination.toString();
                        if (constraint.getType() == ConstraintType.PRIMARY_KEY) {
                            for (String pkColName : constraintColumnNames) {
                                Integer colIdx = columnIndexMap.get(pkColName);
                                if (colIdx != null && processedData.get(colIdx).isEmpty()) {
                                    System.err.println("❌ 违反 PRIMARY KEY 约束 [" + constraint.getName() + "]: 列 '" + pkColName + "' 不能为空");
                                    throw new StorageException("PRIMARY KEY 约束 [" + constraint.getName() + "] 要求列 '" + pkColName + "' 非空");
                                }
                            }
                        }
                        for (Object dataWithSeqObj : dataMap.values()) { // dataWithSeqObj 是 [ID, actualDataList]
                            List<Object> actualExistingRowData;

                            // 1. 安全地提取实际的行数据 List<Object>
                            if (dataWithSeqObj instanceof List<?> && ((List<?>) dataWithSeqObj).size() == 2) {
                                Object secondElement = ((List<?>) dataWithSeqObj).get(1);
                                if (secondElement instanceof List<?>) {
                                    @SuppressWarnings("unchecked")
                                    List<Object> tempRow = (List<Object>) secondElement;
                                    actualExistingRowData = tempRow;
                                } else {
                                    System.err.println("警告: 检查唯一性/主键时，现有行数据格式不符合预期的 [ID, [actualDataList]] 结构 (第二个元素非List)。行对象: " + dataWithSeqObj + ". 跳过此行检查。");
                                    continue;
                                }
                            } else if (dataWithSeqObj instanceof List<?>) {
                                // 尝试兼容旧格式（如果直接存储的是数据行 List<Object>）
                                // 但根据当前的 insertData 逻辑，这应该很少发生或不发生
                                System.out.println("[DEBUG] UNIQUE/PK check: existingRowObj is a List, possibly old direct data format. Attempting to use as is.");
                                @SuppressWarnings("unchecked")
                                List<Object> tempRow = (List<Object>) dataWithSeqObj;
                                actualExistingRowData = tempRow;
                            }
                            else {
                                System.err.println("警告: 检查唯一性/主键时，现有行数据格式未知 (外层非List或List大小不符合预期)。行对象: " + dataWithSeqObj + ". 跳过此行检查。");
                                continue;
                            }

                            StringBuilder existingValueCombination = new StringBuilder();
                            boolean skipRow = false;
                            for (String colName : constraintColumnNames) {
                                Integer colIndex = columnIndexMap.get(colName); // columnIndexMap 是列名到 schema 中索引的映射
                                if (colIndex != null && colIndex < actualExistingRowData.size()) {
                                    // 2. 从 actualExistingRowData (List<Object>) 获取值
                                    Object cellValue = actualExistingRowData.get(colIndex);
                                    // 3. 关键：使用 String.valueOf() 将值安全转换为字符串
                                    existingValueCombination.append(String.valueOf(cellValue)).append("\\0");
                                } else {
                                    System.err.println("警告: 检查唯一性/主键时，现有行缺少约束列 '"+colName+"' (或索引越界). 约束列: " + constraintColumnNames + ", 行数据: " + actualExistingRowData);
                                    skipRow = true;
                                    break;
                                }
                            }

                            if (skipRow) continue;

                            if (existingValueCombination.toString().equals(currentKeyStr)) {
                                System.err.println("❌ 违反 " + constraint.getType() + " 约束 [" + constraint.getName() + "] 在列 " + constraintColumnNames + ". 值: (" + currentKeyStr.replace("\\0", ",") + ")");
                                throw new StorageException("违反 " + constraint.getType() + " 约束 [" + constraint.getName() + "]");
                            }
                        }
                        break;
                    case CHECK:
                        System.out.println("[DEBUG] DataManager: Evaluating CHECK constraint: " + constraint.getName() + " - " + constraint.getCheckCondition());
                        // currentRowValues在这里也使用processedData构建的值
                        if (!validateCheckConstraint(processedData, schemaList, columnIndexMap, constraint, tableName, currentRowValues)) {
                            throw new StorageException("违反 CHECK 约束: " + constraint.getName() + " (" + constraint.getCheckCondition() + ")");
                        }
                        break;
                    case FOREIGN_KEY:
                        System.out.println("[DEBUG] DataManager: Validating FOREIGN KEY constraint: " + constraint.getName() + " on table " + tableName);
                        // currentRowValues 使用的是 processedData 构建的值，这对于FK校验是合适的
                        if (!validateForeignKeyConstraint(db, constraint, currentRowValues, schemaList, tableName, dbName)) {
                            throw new StorageException("违反 FOREIGN KEY 约束: " + constraint.getName() +
                                                       " for table " + tableName + ". Values for columns [" + String.join(",", constraint.getColumns()) +
                                                       "] do not exist in referenced table " + constraint.getReferencedTable() +
                                                       " (" + String.join(",", constraint.getReferencedColumns()) + ")");
                        }
                        break;
                    default:
                        break;
                }
            }

            // 10. 生成自增ID并存储数据
            Long nextId = dataMap.keySet().stream().max(Long::compare).orElse(0L) + 1;

            // 创建包含序号的数据结构（添加一个额外的字段记录插入顺序）
            List<Object> dataWithSequence = new ArrayList<>();
            dataWithSequence.add(nextId); // 第一个元素存储插入顺序

            // 处理INT类型字段，将字符串转换为Long类型
            List<Object> processedDataWithTypes = new ArrayList<>();
            for (int i = 0; i < processedData.size(); i++) {
                String value = processedData.get(i);
                String[] columnDef = schemaList.get(i);
                String dataType = columnDef[1].toUpperCase();

                if (value.isEmpty()) {
                    processedDataWithTypes.add("");
                } else if (dataType.equals("INT") || dataType.equals("INTEGER")) {
                    try {
                        // 原来的代码: 将字符串转换为 Long 对象存储
                        // processedDataWithTypes.add(Long.parseLong(value));

                        // 新的代码: 直接存储已经通过校验的字符串值
                        processedDataWithTypes.add(value);
                    } catch (NumberFormatException e) {
                        // 这段理论上不应该被触发，因为前面的校验阶段 (around line 163-173)
                        // 已经用 Long.parseLong(currentValue) 验证过 value 是可解析的。
                        // 但为了代码的健壮性，如果value在校验后到这里之间被意外修改，这里可以捕获。
                        // 不过，按照当前逻辑，processedData.get(i) 的值与校验时是一致的。
                        System.err.println("❌ 字段 [" + columnDef[0] + "] 值在存储准备阶段转换失败 (这不应发生，因为校验已通过): " + value);
                        return 0;
                    }
                } else {
                    processedDataWithTypes.add(value);
                }
            }

            dataWithSequence.add(processedDataWithTypes); // 第二个元素存储实际数据
            dataMap.put(nextId, dataWithSequence);

            // 移除了 db.commit();
            // System.out.println("✅ 成功在事务中准备插入数据到表 [" + tableName + "]，行ID: " + nextId); // 日志可以保留或调整
            return 1; // 表示操作已在事务中成功排队

        } catch (Exception e) { // 包括StorageException, ConstraintViolationException等
            System.err.println("❌ 事务中的数据插入操作失败 (将由调用者回滚整个事务): " + tableName + " - " + e.getMessage());
            // 移除了内部的: if (db != null) { try { db.rollback(); ... } ... }
            throw e; // 将异常重新抛出，由SQLExecutor等更高层捕获并触发整个事务的回滚
        }
        // 移除了 finally 块及其中的 db.close(); 因为db实例的生命周期由TransactionLogger/DatabaseManager管理
        // 原有的 finally 块内容:
        // finally {
        //     if (db != null && !db.isClosed()) {
        //         try {
        //             db.close();
        //         } catch (Exception e) {
        //             System.err.println("❌ Error closing DB instance in DataManager.insertData for " + dbName + ": " + e.getMessage());
        //         }
        //     }
        // }
    }

    // Helper method to get values for error messages
    private static String getValuesForColumns(List<String> data, List<String> columnNames, Map<String, Integer> columnIndexMap) {
        List<String> values = new ArrayList<>();
        for (String colName : columnNames) {
            Integer index = columnIndexMap.get(colName);
            if (index != null && index < data.size()) {
                values.add("'" + data.get(index) + "'");
            } else {
                values.add("[未知列:" + colName + "]");
            }
        }
        return String.join(", ", values);
    }

    /**
     * 读取表的指定列数据
     * @param dbName 数据库名称
     * @param tableName 表名
     * @param columns 需要获取的列名列表，为null或空则获取所有列
     * @return 数据列表，每行为一个字符串数组
     */
    public static List<String[]> readSelectData(String dbName, String tableName, List<String> columns) {
        // 调用带WHERE条件的版本，但不指定过滤条件
        return readSelectData(dbName, tableName, columns, null, null);
    }

    /**
     * 读取表的指定列数据，同时应用WHERE条件过滤
     * @param dbName 数据库名称
     * @param tableName 表名
     * @param columns 需要获取的列名列表，为null或空则获取所有列
     * @param conditionColumn WHERE条件中的列名
     * @param conditionValue WHERE条件中的值（等值条件）
     * @return 数据列表，每行为一个字符串数组
     */
    @SuppressWarnings("unchecked")
    public static List<String[]> readSelectData(String dbName, String tableName, List<String> columns,
                                               String conditionColumn, String conditionValue) {
        DB db = null;
        // boolean dbFromTransaction = false; // 移除了 dbFromTransaction

        TransactionLogger txLogger = TransactionLogger.getInstance();

        if (!txLogger.isTransactionActive()) {
            System.err.println("错误: readSelectData 操作需要在活动的事务中执行。当前没有活动事务。 (数据库: " + dbName + ", 表: " + tableName + ")");
            return new ArrayList<>();
        }

        String activeTxDbName = txLogger.getTransactionDatabaseName();
        if (activeTxDbName == null || !activeTxDbName.equals(dbName)) {
            System.err.println("错误: readSelectData 操作的数据库 '" + dbName + "' 与当前活动事务的数据库 '" +
                               (activeTxDbName == null ? "未知" : activeTxDbName) + "' 不符。 (表: " + tableName + ")");
            return new ArrayList<>();
        }

        DB tempDb = txLogger.getCurrentTransactionDB();
        if (tempDb == null || tempDb.isClosed()) {
            System.err.println("错误: readSelectData 操作无法执行。与当前活动事务关联的数据库实例 ('" + dbName + "') 无效或已关闭。 (表: " + tableName + ")");
            // 考虑通知 TransactionLogger，如果其管理的 DB 实例已关闭，可能表明状态不一致
            // txLogger.rollbackTransaction(); // 例如，如果认为事务状态已损坏
            return new ArrayList<>();
        }
        db = tempDb; // db 现在总是来自事务

        // 移除了独立获取DB的逻辑:
        // if (db == null) {
        // try {
        // db = systemDBEngine.getDatabase(dbName);
        // ...
        // } catch (Exception e) { ... }
        // }

        // 原有的 if (db == null) 检查现在是多余的，因为如果db为null，上面已经返回了
        // if (db == null) {
        // System.err.println("❌ 最终无法获取数据库 [" + dbName + "] 的有效实例以执行读取操作。");
        // return new ArrayList<>();
        // }

        try {
            // 1. 参数验证 (tableName的null检查保留)
            if (tableName == null) {
                System.err.println("❌ 读取数据参数不完整 (表名为空)");
                return new ArrayList<>();
            }
            // 确保后续所有数据库操作都使用此 'db' 实例 (现在总是事务性db)
            // ... (rest of the original try block, including all MapDB operations, filtering, sorting)

            // 4. 获取表的列信息
            List<Map<String, Object>> columnsInfo = (List<Map<String, Object>>) db
                .hashMap("columns_" + tableName)
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("metadata", new ArrayList<Map<String, Object>>());

            if (columnsInfo.isEmpty()) {
                System.err.println("❌ 表 [" + tableName + "] 结构不存在");
                return new ArrayList<>();
            }

            // 5. 获取所有列名和建立索引映射
            List<String> allColumnNames = new ArrayList<>();
            Map<String, Integer> columnIndexMap = new HashMap<>();

            for (int i = 0; i < columnsInfo.size(); i++) {
                Map<String, Object> colInfo = columnsInfo.get(i);
                String columnName = (String)colInfo.get("name");
                if (columnName != null) {
                    allColumnNames.add(columnName);
                    columnIndexMap.put(columnName.toLowerCase(), i);
                }
            }

            // 6. 如果指定了条件，找到条件列对应的索引 - 先处理WHERE条件
            Integer conditionColumnIndex = null;
            if (conditionColumn != null) {
                for (int i = 0; i < columnsInfo.size(); i++) {
                    Map<String, Object> colInfo = columnsInfo.get(i);
                    String colName = (String) colInfo.get("name");
                    if (colName != null && colName.equalsIgnoreCase(conditionColumn)) {
                        conditionColumnIndex = i;
                        break;
                    }
                }

                if (conditionColumnIndex == null) {
                    System.err.println("❌ 条件列 [" + conditionColumn + "] 在表中不存在");
                    return new ArrayList<>();
                }
            }

            // 7. 检查查询的列 - 在过滤行之后再处理列选择
            List<String> validColumns;
            List<Integer> columnIndexes = new ArrayList<>();

            if (columns == null || columns.isEmpty()) {
                validColumns = new ArrayList<>(allColumnNames);
                for (int i = 0; i < allColumnNames.size(); i++) {
                    columnIndexes.add(i);
                }
            } else {
                validColumns = new ArrayList<>();
                for (String requestedColumn : columns) {
                    for (int i = 0; i < allColumnNames.size(); i++) {
                        if (allColumnNames.get(i).equalsIgnoreCase(requestedColumn)) {
                            validColumns.add(allColumnNames.get(i));
                            columnIndexes.add(i);
                            break;
                        }
                    }
                }
            }

            if (validColumns.isEmpty()) {
                System.err.println("⚠️ 查询的列在表中不存在");
                return new ArrayList<>();
            }

            // 8. 获取表数据
            ConcurrentMap<Long, Object> dataMap = systemDBEngine.getDataStorage(db, tableName);
            if (dataMap == null || dataMap.isEmpty()) {
                System.out.println("ℹ️ 表 [" + tableName + "] 中没有数据");
                List<String[]> resultWithHeader = new ArrayList<>();
                resultWithHeader.add(validColumns.toArray(new String[0]));
                return resultWithHeader;
            }

            // 9. 优化：创建一个结构保存满足WHERE条件的行和序列号，先过滤行再选择列
            List<Map.Entry<Long, List<String>>> filteredRows = new ArrayList<>();

            for (Map.Entry<Long, Object> entry : dataMap.entrySet()) {
                Long key = entry.getKey();
                Object data = entry.getValue();
                List<String> fullRow = null;
                Long sequenceNumber = null;

                if (data instanceof List<?> && ((List<?>)data).size() > 1) {
                    Object seqObj = ((List<?>)data).get(0);
                    if (seqObj instanceof Long) {
                        sequenceNumber = (Long)seqObj;
                    }
                    Object actualData = ((List<?>)data).get(1);
                    if (actualData instanceof List<?>) {
                        @SuppressWarnings("unchecked")
                        List<Object> originalRow = (List<Object>)actualData; // 改为List<Object>类型
                        // 确保所有值都安全转换为String
                        List<String> convertedRow = new ArrayList<>();
                        for (Object item : originalRow) {
                            convertedRow.add(item != null ? String.valueOf(item) : "");
                        }
                        fullRow = convertedRow;
                    }
                } else if (data instanceof List<?>) {
                    sequenceNumber = key;
                    try { 
                        @SuppressWarnings("unchecked")
                        List<Object> originalRow = (List<Object>)data; // 改为List<Object>类型
                        // 确保所有值都安全转换为String
                        List<String> convertedRow = new ArrayList<>();
                        for (Object item : originalRow) {
                            convertedRow.add(item != null ? String.valueOf(item) : "");
                        }
                        fullRow = convertedRow;
                    } catch (ClassCastException e) {
                        System.err.println("⚠️ 数据格式异常: " + e.getMessage());
                        continue;
                    }
                }

                if (fullRow == null) {
                    continue;
                }

                boolean meetCondition = true;
                if (conditionColumn != null && conditionValue != null) {
                    if (conditionColumnIndex < fullRow.size()) {
                        String cellValue = fullRow.get(conditionColumnIndex);
                        if (cellValue == null && conditionValue != null) {
                            meetCondition = false;
                        } else if (cellValue != null && !cellValue.equals(conditionValue)) {
                            meetCondition = false;
                        }
                    } else {
                        meetCondition = false;
                    }
                }

                if (meetCondition) {
                    Map.Entry<Long, List<String>> rowEntry = new AbstractMap.SimpleEntry<>(sequenceNumber, fullRow);
                    filteredRows.add(rowEntry);
                }
            }

            filteredRows.sort((e1, e2) -> e1.getKey().compareTo(e2.getKey()));

            List<String[]> result = new ArrayList<>();
            for (Map.Entry<Long, List<String>> entry : filteredRows) {
                List<String> fullRow = entry.getValue();
                String[] selectedRow = new String[validColumns.size()];
                for (int i = 0; i < columnIndexes.size(); i++) {
                    int index = columnIndexes.get(i);
                    if (index < fullRow.size()) {
                        // 使用String.valueOf确保所有类型(包括Long)都正确转换为String
                        Object cellValue = fullRow.get(index);
                        selectedRow[i] = String.valueOf(cellValue);
                    } else {
                        selectedRow[i] = "NULL";
                    }
                }
                result.add(selectedRow);
            }

            List<String[]> resultWithHeader = new ArrayList<>();
            resultWithHeader.add(validColumns.toArray(new String[0]));
            resultWithHeader.addAll(result);

            if (conditionColumn != null && conditionValue != null) {
                System.out.println("✅ 成功从表 [" + tableName + "] 读取符合条件 [" + conditionColumn + "=" + conditionValue +
                    "] 的 " + result.size() + " 行数据 (在事务上下文中)");
            } else {
                System.out.println("✅ 成功从表 [" + tableName + "] 读取 " + result.size() + " 行数据 (在事务上下文中)");
            }

            return resultWithHeader;
        } catch (Exception e) {
            System.err.println("❌ 读取数据失败: " + e.getMessage());
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            System.err.println("堆栈跟踪:\\n" + sw.toString().replace("\\t", "    "));
            return new ArrayList<>();
        } finally {
            // DB实例来自TransactionLogger，不由本方法关闭。
            // 移除了: if (db != null && !dbFromTransaction && !db.isClosed()) { ... db.close() ... }
        }
    }

    /**
     * 读取表的所有列数据（兼容旧版本）
     * @param dbName 数据库名称
     * @param tableName 表名
     * @return 数据列表，每行为一个字符串数组
     */
    public static List<String[]> readSelectData(String dbName, String tableName) {
        // 调用带列参数的版本，但不指定列（获取所有列）
        return readSelectData(dbName, tableName, null, null, null);
    }

    /**
     * 更新表的列结构信息
     * 该方法可用于添加列、删除列或修改列定义
     *
     * @param dbName 数据库名称
     * @param tableName 表名
     * @param columnOp 操作类型：ADD(添加)、DROP(删除)、MODIFY(修改)
     * @param columnDef 列定义信息 [列名, 数据类型, 长度, 其他属性...]
     * @return 1表示成功，0表示失败
     */
    @SuppressWarnings("unchecked")
    public static int updateColumnStructure(String dbName, String tableName, String columnOp, String[] columnDef) {
        // 1. 从TransactionLogger获取DB实例
        DB db = TransactionLogger.getInstance().getCurrentTransactionDB();

        // 2. 检查事务状态和数据库上下文
        if (db == null) {
            System.err.println("错误: updateColumnStructure 操作需要在活动的事务中执行。");
            // throw new IllegalStateException("updateColumnStructure 操作需要在活动的事务中执行。");
            return 0;
        }
        String activeTransactionDbName = TransactionLogger.getInstance().getTransactionDatabaseName();
        if (activeTransactionDbName == null || !activeTransactionDbName.equals(dbName)) {
            System.err.println("错误: updateColumnStructure 操作的数据库 '" + dbName + "' 与当前活动事务的数据库 '" + activeTransactionDbName + "' 不符。");
            // throw new IllegalStateException("数据库上下文与当前活动事务不匹配。");
            return 0;
        }
        if (db.isClosed()) {
            System.err.println("错误: 与当前事务关联的数据库实例已关闭。事务将被回滚。");
            TransactionLogger.getInstance().rollbackTransaction();
            return 0;
        }

        try {
            // 3. 参数验证 (保留原有逻辑)
            // if (dbName == null || tableName == null || columnOp == null || columnDef == null) { // dbName检查已移除
            if (tableName == null || columnOp == null || columnDef == null) {
                System.err.println("❌ 列操作参数不完整 (表名、操作类型或列定义为空)");
                return 0;
            }
            // ... (其他原有参数验证逻辑)

            // 4. 检查表是否存在，获取列信息 (使用事务db实例)
            Map<String, Object> tableInfo = (Map<String, Object>) db
                .hashMap("TableInfo")
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("tables", new HashMap<String, Object>());

            List<String> tablesList = tableInfo != null ?
                (List<String>) tableInfo.getOrDefault("tablesList", new ArrayList<String>()) :
                new ArrayList<>();

            if (!tablesList.contains(tableName)) {
                System.err.println("❌ 表 [" + tableName + "] 不存在");
                return 0;
            }

            List<Map<String, Object>> columnsInfo = (List<Map<String, Object>>) db
                .hashMap("columns_" + tableName)
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("metadata", new ArrayList<Map<String, Object>>());

            // ... (columnIndexMap, columnStructureChanged, switch(columnOp) 等核心逻辑保留)
            // 在 switch case 中调用 updateDataForColumnAdd 和 updateDataForColumnDrop 时，
            // 它们将使用同一个事务性 db 实例。
            String columnName = columnDef[0]; // Moved up for clarity before switch
            columnOp = columnOp.toUpperCase();

            Map<String, Integer> columnIndexMap = new HashMap<>();
            for (int i = 0; i < columnsInfo.size(); i++) {
                String colName = (String) columnsInfo.get(i).get("name");
                if (colName != null) {
                    columnIndexMap.put(colName, i);
                }
            }
            boolean columnStructureChanged = false;

            switch (columnOp) {
                case "ADD":
                    // ... (ADD case 逻辑保留, 调用 updateDataForColumnAdd(db, tableName, ...))
                    if (columnDef.length < 3) { /* error */ return 0; }
                    if (columnIndexMap.containsKey(columnName)) { /* error */ return 0; }
                    Map<String, Object> newColumnInfo = new HashMap<>();
                    newColumnInfo.put("name", columnName);
                    newColumnInfo.put("type", columnDef[1]);
                    newColumnInfo.put("index", columnsInfo.size());
                    try { newColumnInfo.put("length", Integer.parseInt(columnDef[2])); }
                    catch (NumberFormatException e) { /* error */ return 0; }
                    newColumnInfo.put("nullable", true);
                    if (columnDef.length > 3) {
                        for (int i = 3; i < columnDef.length; i++) {
                            if ("NOT NULL".equalsIgnoreCase(columnDef[i])) newColumnInfo.put("nullable", false);
                        }
                    }
                    columnsInfo.add(newColumnInfo);
                    columnStructureChanged = true;
                    System.out.println("✅ 已在事务中准备添加列 [" + columnName + "]");
                    updateDataForColumnAdd(db, tableName, columnsInfo.size() - 1); // 使用事务db
                    break;
                case "DROP":
                    // ... (DROP case 逻辑保留, 调用 updateDataForColumnDrop(db, tableName, ...))
                    Integer dropIndex = columnIndexMap.get(columnName);
                    if (dropIndex == null) { /* error */ return 0; }
                    columnsInfo.remove(dropIndex.intValue());
                    columnStructureChanged = true;
                    for (int i = 0; i < columnsInfo.size(); i++) { columnsInfo.get(i).put("index", i); }
                    System.out.println("✅ 已在事务中准备删除列 [" + columnName + "]");
                    updateDataForColumnDrop(db, tableName, dropIndex); // 使用事务db
                    break;
                case "MODIFY":
                    // ... (MODIFY case 逻辑保留)
                    if (columnDef.length < 3) { /* error */ return 0; }
                    Integer modifyIndex = columnIndexMap.get(columnName);
                    if (modifyIndex == null) { /* error */ return 0; }
                    Map<String, Object> colInfo = columnsInfo.get(modifyIndex);
                    colInfo.put("type", columnDef[1]);
                    try { colInfo.put("length", Integer.parseInt(columnDef[2])); }
                    catch (NumberFormatException e) { /* error */ return 0; }
                    if (columnDef.length > 3) {
                        colInfo.put("nullable", true);
                        for (int i = 3; i < columnDef.length; i++) {
                            if ("NOT NULL".equalsIgnoreCase(columnDef[i])) colInfo.put("nullable", false);
                        }
                    }
                    columnStructureChanged = true;
                    System.out.println("✅ 已在事务中准备修改列 [" + columnName + "]");
                    break;
                default:
                    System.err.println("❌ 不支持的列操作: " + columnOp);
                    return 0;
            }

            if (columnStructureChanged) {
                db.hashMap("columns_" + tableName) // 使用事务db
                  .keySerializer(Serializer.STRING)
                  .valueSerializer(Serializer.JAVA)
                  .createOrOpen()
                  .put("metadata", columnsInfo);
                // 移除了 db.commit();
                System.out.println("✅ 表 [" + tableName + "] 结构已在事务中准备更新");
                return 1; // 操作已在事务中排队
            } else {
                System.out.println("ℹ️ 未对表 [" + tableName + "] 结构进行任何修改");
                return 0; // 或1，取决于是否认为"无操作"是成功
            }

        } catch (Exception e) {
            System.err.println("❌ 事务中的更新列结构操作失败 (将由调用者回滚整个事务): " + tableName + " - " + e.getMessage());
            // 移除了内部的 db.rollback();
            throw e; // 将异常重新抛出
        }
        // 移除了 finally 块及其中的 db.close();
    }

    /**
     * 添加列后更新现有数据 (辅助方法)
     * 为所有行添加新列的默认值（空字符串）
     */
    @SuppressWarnings("unchecked")
    private static void updateDataForColumnAdd(DB db, String tableName, int newColumnIndex) {
        // 此方法现在由 updateColumnStructure 在事务中调用，db参数是事务性db
        try {
            ConcurrentMap<Long, Object> dataMap = systemDBEngine.getDataStorage(db, tableName); // 使用传入的事务db
            if (dataMap == null) { // 添加对dataMap null的检查
                System.err.println("错误(updateDataForColumnAdd): 表 \'" + tableName + "\' 的dataMap为null。");
                // 如果dataMap为null，直接抛出异常，而不是仅仅返回。
                // 这表示一个更严重的问题，应该中断操作并可能导致事务回滚。
                throw new RuntimeException("无法为表 " + tableName + " 获取数据存储以添加列数据。");
            }
            int updatedRows = 0;
            // ... (原有的遍历和更新逻辑保留)
            for (Map.Entry<Long, Object> entry : dataMap.entrySet()) {
                Long key = entry.getKey();
                Object data = entry.getValue();
                boolean updated = false;
                if (data instanceof List) { // 简化了类型检查，具体实现可能需要更严格的检查
                    List<?> rowData = (List<?>) data;
                    if (rowData.size() > 1 && rowData.get(1) instanceof List) { // New format
                        List<Object> outer = new ArrayList<>(rowData);
                        List<String> inner = new ArrayList<>();
                        for (Object item : (List<?>)outer.get(1)) {
                            inner.add(item != null ? item.toString() : "");
                        }
                        while (inner.size() <= newColumnIndex) { inner.add(""); }
                        outer.set(1, inner);
                        dataMap.put(key, outer);
                        updated = true;
                    } else { // Old format or simple list
                        List<String> row = new ArrayList<>();
                        for (Object item : rowData) {
                            row.add(item != null ? item.toString() : "");
                        }
                        while (row.size() <= newColumnIndex) { row.add(""); }
                        dataMap.put(key, row);
                        updated = true;
                    }
                    if (updated) updatedRows++;
                }
            }
            // 移除了 db.commit();
            System.out.println("✅ (事务内)已为 " + updatedRows + " 行数据添加新列 [索引: " + newColumnIndex + "] 的默认值");
        } catch (Exception e) {
            System.err.println("❌ (事务内)添加列数据时发生错误: " + e.getMessage());
            // 直接向上抛出原始异常或包装后的异常，以便上层统一处理事务
            throw e;
        }
    }

    /**
     * 删除列后更新现有数据 (辅助方法)
     * 从所有行中删除指定列的数据
     */
    @SuppressWarnings("unchecked")
    private static void updateDataForColumnDrop(DB db, String tableName, int dropColumnIndex) {
        // 此方法现在由 updateColumnStructure 在事务中调用，db参数是事务性db
        try {
            ConcurrentMap<Long, Object> dataMap = systemDBEngine.getDataStorage(db, tableName); // 使用传入的事务db
            if (dataMap == null) { // 添加对dataMap null的检查
                System.err.println("错误(updateDataForColumnDrop): 表 \'" + tableName + "\' 的dataMap为null。");
                // 如果dataMap为null，直接抛出异常
                throw new RuntimeException("无法为表 " + tableName + " 获取数据存储以删除列数据。");
            }
            int updatedRows = 0;
            // ... (原有的遍历和更新逻辑保留)
             for (Map.Entry<Long, Object> entry : dataMap.entrySet()) {
                Long key = entry.getKey();
                Object data = entry.getValue();
                boolean updated = false;
                if (data instanceof List) { // 简化类型检查
                    List<?> rowData = (List<?>) data;
                    if (rowData.size() > 1 && rowData.get(1) instanceof List) { // New format
                        List<Object> outer = new ArrayList<>(rowData);
                        List<String> inner = new ArrayList<>();
                        for (Object item : (List<?>)outer.get(1)) {
                            inner.add(item != null ? item.toString() : "");
                        }
                        if (inner.size() > dropColumnIndex) { inner.remove(dropColumnIndex); outer.set(1, inner); dataMap.put(key, outer); updated = true;}
                    } else { // Old format or simple list
                         List<String> row = new ArrayList<>();
                         for (Object item : rowData) {
                             row.add(item != null ? item.toString() : "");
                         }
                        if (row.size() > dropColumnIndex) { row.remove(dropColumnIndex); dataMap.put(key, row); updated = true; }
                    }
                    if (updated) updatedRows++;
                }
            }
            // 移除了 db.commit();
            System.out.println("✅ (事务内)已从 " + updatedRows + " 行数据中删除列 [索引: " + dropColumnIndex + "]");
        } catch (Exception e) {
            System.err.println("❌ (事务内)删除列数据时发生错误: " + e.getMessage());
            // 直接向上抛出原始异常或包装后的异常
            throw e;
        }
    }

    /*
    * 参数列表解释：
    * dbName：数据库名；tableName：表名；selectedColumns：选中的列名。ps：注意列名的无序性
    * */



    /*
    * 功能：删除特定的行，目前只支持一个等值语句
    * dbName：数据库名；
    * tableName：表名；
    * conditionColumn：选中的列名。
    * conditionValue：要求该列等于的值
    * 若 conditionColumn和conditionValue都为null，删除全量数据
    * */
    @SuppressWarnings("unchecked")
    public static int deleteData(String dbName, String tableName, String conditionColumn, String conditionValue) {
        // 1. 从TransactionLogger获取DB实例
        DB db = TransactionLogger.getInstance().getCurrentTransactionDB();

        // 2. 检查事务状态和数据库上下文
        if (db == null) {
            System.err.println("错误: deleteData 操作需要在活动的事务中执行。");
            // throw new IllegalStateException("deleteData 操作需要在活动的事务中执行。");
            return 0;
        }
        String activeTransactionDbName = TransactionLogger.getInstance().getTransactionDatabaseName();
        if (activeTransactionDbName == null || !activeTransactionDbName.equals(dbName)) {
            System.err.println("错误: deleteData 操作的数据库 '" + dbName + "' 与当前活动事务的数据库 '" + activeTransactionDbName + "' 不符。");
            // throw new IllegalStateException("数据库上下文与当前活动事务不匹配。");
            return 0;
        }
        if (db.isClosed()) {
            System.err.println("错误: 与当前事务关联的数据库实例已关闭。事务将被回滚。");
            TransactionLogger.getInstance().rollbackTransaction();
            return 0;
        }

        try {
            // 3. 参数验证 (保留原有逻辑, dbName的null检查已间接完成)
            // if (dbName == null || tableName == null) { // dbName检查已移除
            if (tableName == null) { // tableName 仍然需要检查
                System.err.println("❌ 删除数据参数不完整 (表名为空)");
                return 0;
            }

            // 4. 检查表是否存在 (使用事务db实例)
            Map<String, Object> tableInfo = (Map<String, Object>) db
                .hashMap("TableInfo")
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("tables", new HashMap<String, Object>());

            List<String> tablesList = tableInfo != null ?
                (List<String>) tableInfo.getOrDefault("tablesList", new ArrayList<String>()) :
                    new ArrayList<>();

            if (!tablesList.contains(tableName)) {
                System.err.println("❌ 表 [" + tableName + "] 不存在");
                return 0;
            }

            // 5. 获取表的列信息 (使用事务db实例)
            List<Map<String, Object>> columnsInfo = (List<Map<String, Object>>) db
                .hashMap("columns_" + tableName)
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("metadata", new ArrayList<Map<String, Object>>());

            if (columnsInfo.isEmpty()) {
                System.err.println("❌ 表 [" + tableName + "] 结构不存在");
                return 0;
            }

            // 6. 获取表数据 (使用事务db实例)
            ConcurrentMap<Long, Object> dataMap = systemDBEngine.getDataStorage(db, tableName);
            if (dataMap == null || dataMap.isEmpty()) {
                System.out.println("ℹ️ 表 [" + tableName + "] 中没有数据可删除");
                return 0;
            }

            // 7. 如果没有指定条件列和条件值，删除所有数据
            if (conditionColumn == null && conditionValue == null) {
                int count = dataMap.size();
                dataMap.clear(); // Operates on the transactional dataMap
                // 移除了 db.commit();
                System.out.println("✅ 已在事务中准备删除表 [" + tableName + "] 中的所有 " + count + " 行数据");
                return count;
            }

            // 8. 如果指定了条件，找到条件列对应的索引
            Integer conditionColumnIndex = null;
            for (int i = 0; i < columnsInfo.size(); i++) {
                Map<String, Object> colInfo = columnsInfo.get(i);
                String colName = (String) colInfo.get("name");
                if (colName != null && colName.equalsIgnoreCase(conditionColumn)) {
                    conditionColumnIndex = i;
                    break;
                }
            }
            if (conditionColumnIndex == null && conditionColumn != null) { // conditionColumn is not null but not found
                System.err.println("❌ 条件列 [" + conditionColumn + "] 在表中不存在");
                return 0;
            }

            List<Map.Entry<Long, Object>> allEntries = new ArrayList<>();
            List<Long> keysToDelete = new ArrayList<>();

            for (Map.Entry<Long, Object> entry : dataMap.entrySet()) {
                allEntries.add(entry); // For re-sequencing later
                Long key = entry.getKey();
                Object data = entry.getValue();
                List<String> row = null;

                if (data instanceof List<?> && ((List<?>)data).size() > 1 && ((List<?>)data).get(1) instanceof List<?>) {
                    // 修改为安全的类型转换
                    Object listData = ((List<?>)data).get(1);
                    @SuppressWarnings("unchecked")
                    List<Object> originalRow = (List<Object>)listData;
                    // 确保所有值都安全转换为String
                    List<String> convertedRow = new ArrayList<>();
                    for (Object item : originalRow) {
                        convertedRow.add(item != null ? String.valueOf(item) : "");
                    }
                    row = convertedRow;
                } else if (data instanceof List<?>) {
                    try { 
                        // 修改为安全的类型转换
                        @SuppressWarnings("unchecked")
                        List<Object> originalRow = (List<Object>)data;
                        // 确保所有值都安全转换为String
                        List<String> convertedRow = new ArrayList<>();
                        for (Object item : originalRow) {
                            convertedRow.add(item != null ? String.valueOf(item) : "");
                        }
                        row = convertedRow;
                    } catch (ClassCastException e) {
                        System.err.println("⚠️ 数据格式异常 (deleteData): " + e.getMessage());
                        continue;
                    }
                }

                if (row != null && conditionColumnIndex != null && conditionColumnIndex < row.size()) {
                    String cellValue = row.get(conditionColumnIndex);
                    if ((cellValue == null && conditionValue == null) ||
                        (cellValue != null && cellValue.equals(conditionValue))) {
                        keysToDelete.add(key);
                    }
                }
            }

            int deletedCount = keysToDelete.size();
            if (deletedCount == 0) {
                System.out.println("ℹ️ 没有找到符合条件的数据行可删除");
                return 0;
            }

            for (Long key : keysToDelete) {
                dataMap.remove(key); // Operates on the transactional dataMap
            }

            // 重新整理序列号 (保留)
            allEntries.removeIf(entry -> keysToDelete.contains(entry.getKey()));
            allEntries.sort((e1, e2) -> {
                try {
                    Long seq1 = null, seq2 = null;
                    if (e1.getValue() instanceof List<?> && !((List<?>) e1.getValue()).isEmpty()) {
                        Object seqObj1 = ((List<?>)e1.getValue()).get(0);
                        if (seqObj1 instanceof Long) seq1 = (Long)seqObj1;
                    }
                    if (e2.getValue() instanceof List<?> && !((List<?>) e2.getValue()).isEmpty()) {
                        Object seqObj2 = ((List<?>)e2.getValue()).get(0);
                        if (seqObj2 instanceof Long) seq2 = (Long)seqObj2;
                    }
                    if (seq1 != null && seq2 != null) return seq1.compareTo(seq2);
                    return e1.getKey().compareTo(e2.getKey());
                } catch (Exception e) { return e1.getKey().compareTo(e2.getKey()); }
            });
            for (int i = 0; i < allEntries.size(); i++) {
                Map.Entry<Long, Object> entry = allEntries.get(i);
                Object data = entry.getValue();
                if (data instanceof List<?> && !((List<?>) data).isEmpty()) {
                    ((List<Object>)data).set(0, (long)(i + 1));
                    dataMap.put(entry.getKey(), data); // Operates on the transactional dataMap
                }
            }

            // 移除了 db.commit();
            System.out.println("✅ 已在事务中准备从表 [" + tableName + "] 中删除 " + deletedCount + " 行数据");
            // System.out.println("✅ 已在事务中准备重新整理表 [" + tableName + "] 的数据序列号，现有 " + allEntries.size() + " 行数据"); // Log can be more specific
            return deletedCount; // 操作已在事务中排队

        } catch (Exception e) {
            System.err.println("❌ 事务中的数据删除操作失败 (将由调用者回滚整个事务): " + tableName + " - " + e.getMessage());
            // 移除了内部的 db.rollback();
            throw e; // 将异常重新抛出
        }
        // 移除了 finally 块及其中的 db.close();
    }

    /*
     * 功能：特定的行，目前只支持一个等值语句
     * dbName：数据库名；
     * tableName：表名；
     * where条件，目前只支持单个等值式，先筛选满足conditionColumn=conditionValue的列，
     * 若 conditionColumn和conditionValue都为null，更改全量数据
     * Columns:对选定行要更改的字段名
     * values:选定行要改成的值，Columns第i个元素对应的字段要改成values第i个元素对应的值
     * */
    @SuppressWarnings("unchecked")
    public static int updateData(String dbName, String tableName, String conditionColumn, String conditionValue, List<String> Columns, List<String> values, List<String[]> schemaList) { // 添加 schemaList 参数
        // 1. 从TransactionLogger获取DB实例
        DB db = TransactionLogger.getInstance().getCurrentTransactionDB();

        // 2. 检查事务状态和数据库上下文
        if (db == null) {
            System.err.println("错误: updateData 操作需要在活动的事务中执行。");
            // throw new IllegalStateException("updateData 操作需要在活动的事务中执行。");
            return 0;
        }
        String activeTransactionDbName = TransactionLogger.getInstance().getTransactionDatabaseName();
        if (activeTransactionDbName == null || !activeTransactionDbName.equals(dbName)) {
            System.err.println("错误: updateData 操作的数据库 '" + dbName + "' 与当前活动事务的数据库 '" + activeTransactionDbName + "' 不符。");
            // throw new IllegalStateException("数据库上下文与当前活动事务不匹配。");
            return 0;
        }
        if (db.isClosed()) {
            System.err.println("错误: 与当前事务关联的数据库实例已关闭。事务将被回滚。");
            TransactionLogger.getInstance().rollbackTransaction();
            return 0;
        }

        try {
            // 3. 参数验证 (保留原有逻辑, dbName的null检查已间接完成)
            // if (dbName == null || tableName == null) { // dbName检查已移除
            if (tableName == null) { // tableName 仍然需要检查
                System.err.println("❌ 更新数据参数不完整 (表名为空)");
                return 0;
            }
            if (Columns == null || values == null || Columns.isEmpty() || values.isEmpty()) {
                System.err.println("❌ 更新数据参数不完整: 缺少更新的列和值");
                return 0;
            }
            if (Columns.size() != values.size()) {
                System.err.println("❌ 更新列和值的数量不匹配: 列数量=" + Columns.size() + ", 值数量=" + values.size());
                return 0;
            }

            // 4. 检查表是否存在 (使用事务db实例)
            Map<String, Object> tableInfo = (Map<String, Object>) db
                .hashMap("TableInfo")
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("tables", new HashMap<String, Object>());

            List<String> tablesList = tableInfo != null ?
                (List<String>) tableInfo.getOrDefault("tablesList", new ArrayList<String>()) :
                    new ArrayList<>();

            if (!tablesList.contains(tableName)) {
                System.err.println("❌ 表 [" + tableName + "] 不存在");
                return 0;
            }

            // 5. 获取表的列信息 (使用事务db实例)
            List<Map<String, Object>> columnsInfo = (List<Map<String, Object>>) db
                .hashMap("columns_" + tableName)
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("metadata", new ArrayList<Map<String, Object>>());

            if (columnsInfo.isEmpty()) {
                System.err.println("❌ 表 [" + tableName + "] 结构不存在");
                return 0;
            }

            // 6. 获取所有列名和索引的映射
            Map<String, Integer> columnIndexMap = new HashMap<>();
            Map<String, Map<String, Object>> columnInfoMap = new HashMap<>();
            for (int i = 0; i < columnsInfo.size(); i++) {
                Map<String, Object> colInfo = columnsInfo.get(i);
                String colName = (String) colInfo.get("name");
                if (colName != null) {
                    columnIndexMap.put(colName.toLowerCase(), i);
                    columnInfoMap.put(colName.toLowerCase(), colInfo);
                }
            }

            // 7. 获取表数据 (使用事务db实例)
            ConcurrentMap<Long, Object> dataMap = systemDBEngine.getDataStorage(db, tableName);
            if (dataMap == null || dataMap.isEmpty()) {
                System.out.println("ℹ️ 表 [" + tableName + "] 中没有数据可更新");
                return 0;
            }

            // 8. 遍历数据并根据条件更新符合条件的行
            int updatedCount = 0;
            List<Map.Entry<Long, Object>> allEntries = new ArrayList<>();
            for (Map.Entry<Long, Object> entry : dataMap.entrySet()) {
                allEntries.add(entry);
            }

            for (Map.Entry<Long, Object> entry : allEntries) {
                Long key = entry.getKey();
                Object data = entry.getValue();
                List<String> row = null;
                Object sequenceInfo = null;
                boolean isNewFormat = false;

                if (data instanceof List<?> && ((List<?>)data).size() > 1) {
                    sequenceInfo = ((List<?>)data).get(0);
                    Object actualData = ((List<?>)data).get(1);
                    if (actualData instanceof List<?>) {
                        @SuppressWarnings("unchecked")
                        List<Object> originalRow = (List<Object>)actualData;
                        // 确保所有值都安全转换为String
                        List<String> convertedRow = new ArrayList<>();
                        for (Object item : originalRow) {
                            convertedRow.add(item != null ? String.valueOf(item) : "");
                        }
                        row = convertedRow;
                        isNewFormat = true;
                    }
                } else if (data instanceof List<?>) {
                    try {
                        @SuppressWarnings("unchecked")
                        List<Object> originalRow = (List<Object>)data;
                        // 确保所有值都安全转换为String
                        List<String> convertedRow = new ArrayList<>();
                        for (Object item : originalRow) {
                            convertedRow.add(item != null ? String.valueOf(item) : "");
                        }
                        row = convertedRow;
                    } catch (ClassCastException e) {
                        continue;
                    }
                }

                boolean shouldUpdate = false;
                Integer conditionIdx = columnIndexMap.get(conditionColumn != null ? conditionColumn.toLowerCase() : null);

                if (conditionColumn == null && conditionValue == null) {
                    shouldUpdate = true;
                } else if (row != null && conditionIdx != null && conditionIdx < row.size()) {
                    String cellValue = row.get(conditionIdx);
                    if ((cellValue == null && conditionValue == null) ||
                        (cellValue != null && cellValue.equals(conditionValue))) {
                        shouldUpdate = true;
                    }
                }

                if (shouldUpdate && row != null) {
                    List<String> originalRowForUniqueCheck = new ArrayList<>(row); // 保存原始行用于唯一性检查比较

                    List<Integer> updateColumnIndexes = new ArrayList<>();
                    List<String> columnsToUpdateNames = new ArrayList<>(); // 用于后续的currentRowValues构建

                    for (String colName : Columns) {
                        Integer colIdx = columnIndexMap.get(colName.toLowerCase());
                        if (colIdx == null) {
                            System.err.println("错误: UPDATE语句尝试更新不存在的列: " + colName);
                            throw new StorageException("UPDATE语句尝试更新不存在的列: " + colName);
                        }
                        updateColumnIndexes.add(colIdx);
                        columnsToUpdateNames.add(colName); // schemaList中的列名大小写可能不一致
                    }

                    // 创建更新后的行副本用于校验
                    List<String> updatedRowCandidate = new ArrayList<>(row);
                    for (int i = 0; i < updateColumnIndexes.size(); i++) {
                        int colIndex = updateColumnIndexes.get(i);
                        String newValue = values.get(i);
                        // TODO: 在这里应用与insertData中类似的预处理和类型校验 newValue?
                        // 例如: processValue(newValue, schemaList.get(colIndex)...)
                        // 当前直接赋值
                        while (updatedRowCandidate.size() <= colIndex) { updatedRowCandidate.add(""); }
                        updatedRowCandidate.set(colIndex, newValue);
                    }

                    // 构建 currentRowValues map 以便传递给约束校验方法
                    // 这个 map 需要反映 *更新后* 的行数据
                    Map<String, String> updatedRowMap = new HashMap<>();
                    for(int i=0; i<schemaList.size(); i++){
                        String schemaColName = schemaList.get(i)[0];
                        if (i < updatedRowCandidate.size()){
                            updatedRowMap.put(schemaColName, updatedRowCandidate.get(i));
                        } else {
                            updatedRowMap.put(schemaColName, ""); // 如果行较短，补充空值
                        }
                    }

                    // **** 执行约束校验 ****
                    // 从元数据加载约束 (与insertData中类似，但这里可能需要优化，避免重复加载)
                    // 简化: 假设 constraints 变量已从方法开始处加载并可用，或者重新加载一次
                    List<TableConstraint> constraintsForUpdate = new ArrayList<>();
                    List<Map<String, Object>> constraintsMapListUpdate = (List<Map<String, Object>>) db
                        .hashMap("constraints_" + tableName)
                        .keySerializer(Serializer.STRING).valueSerializer(Serializer.JAVA)
                        .createOrOpen().getOrDefault("metadata", new ArrayList<Map<String, Object>>());
                    for (Map<String, Object> constraintMap : constraintsMapListUpdate) {
                        try { constraintsForUpdate.add(TableConstraint.fromMap(constraintMap)); }
                        catch (IllegalArgumentException e) { System.err.println("⚠️ UPDATE: 加载约束失败: " + e.getMessage()); }
                    }

                    for (TableConstraint constraint : constraintsForUpdate) {
                        switch (constraint.getType()) {
                            case NOT_NULL:
                                for (String colName : constraint.getColumns()) {
                                    if (updatedRowMap.get(colName) == null || updatedRowMap.get(colName).isEmpty()) {
                                        throw new StorageException("违反 NOT NULL 约束 (on UPDATE): " + constraint.getName() + " on column " + colName);
                                    }
                                }
                                break;
                            case CHECK:
                                if (!validateCheckConstraint(updatedRowCandidate, schemaList, columnIndexMap, constraint, tableName, updatedRowMap)) {
                                    throw new StorageException("违反 CHECK 约束 (on UPDATE): " + constraint.getName() + " (" + constraint.getCheckCondition() + ")");
                                }
                                break;
                            case FOREIGN_KEY:
                                if (!validateForeignKeyConstraint(db, constraint, updatedRowMap, schemaList, tableName, dbName)) {
                                    throw new StorageException("违反 FOREIGN KEY 约束 (on UPDATE): " + constraint.getName() + ". Values for " + constraint.getColumns() + " not in " + constraint.getReferencedTable());
                                }
                                break;
                            case UNIQUE:
                            case PRIMARY_KEY:
                                // 重新校验唯一性/主键约束比较复杂，因为它需要比较整个表
                                // 特别是当被更新的列是唯一键/主键的一部分时。
                                // 简化处理：如果主键/唯一键的任何部分被修改，则需要执行完整的唯一性检查。
                                // 当前实现暂不在这里执行修改后的唯一键校验，依赖于用户不通过UPDATE创建重复的唯一键。
                                // 一个更完整的实现需要比较 updatedRowMap 中的键值与表中其他行（排除当前行修改前的值）。
                                System.out.println("[INFO] UPDATE: UNIQUE/PRIMARY KEY re-validation for modified values is not fully implemented here. Assumes data integrity maintained by other means or non-key updates.");
                                break;
                            default: break;
                        }
                    }
                    // **** 约束校验结束 ****

                    // 如果所有校验通过，则实际更新数据
                    Object newDataToPut;
                    if (isNewFormat) {
                        List<Object> updatedDataFormat = new ArrayList<>();
                        updatedDataFormat.add(sequenceInfo);
                        updatedDataFormat.add(updatedRowCandidate);
                        newDataToPut = updatedDataFormat;
                    } else {
                        newDataToPut = updatedRowCandidate;
                    }
                    dataMap.put(key, newDataToPut);
                    updatedCount++;
                }
            }

            if (updatedCount == 0) {
                System.out.println("ℹ️ 没有找到符合条件的数据行可更新");
                return 0;
            }

            // 重新整理序列号逻辑 (保留，因为它操作 dataMap)
            if (updatedCount > 0) {
                allEntries.clear();
                for (Map.Entry<Long, Object> entry : dataMap.entrySet()) { allEntries.add(entry); }
                allEntries.sort((e1, e2) -> {
                    try {
                        Long seq1 = null, seq2 = null;
                        if (e1.getValue() instanceof List<?> && ((List<?>)e1.getValue()).size() > 0) {
                            Object seqObj1 = ((List<?>)e1.getValue()).get(0);
                            if (seqObj1 instanceof Long) seq1 = (Long)seqObj1;
                        }
                        if (e2.getValue() instanceof List<?> && ((List<?>)e2.getValue()).size() > 0) {
                            Object seqObj2 = ((List<?>)e2.getValue()).get(0);
                            if (seqObj2 instanceof Long) seq2 = (Long)seqObj2;
                        }
                        if (seq1 != null && seq2 != null) return seq1.compareTo(seq2);
                        return e1.getKey().compareTo(e2.getKey());
                    } catch (Exception e) { return e1.getKey().compareTo(e2.getKey()); }
                });
                for (int i = 0; i < allEntries.size(); i++) {
                    Map.Entry<Long, Object> entry = allEntries.get(i);
                    Object data = entry.getValue();
                    if (data instanceof List<?> && ((List<?>)data).size() > 0) {
                        ((List<Object>)data).set(0, (long)(i + 1));
                        dataMap.put(entry.getKey(), data);
                    }
                }
            }

            // 移除了 db.commit();
            System.out.println("✅ 已在事务中准备更新表 [" + tableName + "] 中的 " + updatedCount + " 行数据");
            return updatedCount; // 操作已在事务中排队

        } catch (Exception e) {
            System.err.println("❌ 事务中的数据更新操作失败 (将由调用者回滚整个事务): " + tableName + " - " + e.getMessage());
            // 移除了内部的 db.rollback();
            throw e; // 将异常重新抛出
        }
        // 移除了 finally 块及其中的 db.close();
    }

    private static boolean validateCheckConstraint(List<String> processedData, // 当前行经过初步处理的值
                                                   List<String[]> schemaList, // 包含所有列的定义 (name, type, length)
                                                   Map<String, Integer> columnIndexMap, // 列名 -> processedData 中的索引
                                                   TableConstraint checkConstraint,
                                                   String tableName,
                                                   Map<String, String> currentRowValues // 当前行原始值的一个映射，列名 -> 值
                                                   ) {
        String condition = checkConstraint.getCheckCondition();
        List<String> involvedColumns = checkConstraint.getColumns(); // 这些列名应该在创建约束时从表达式中解析得到

        if (condition == null || condition.trim().isEmpty()) {
            System.err.println("警告: CHECK 约束 '" + checkConstraint.getName() + "' 的条件为空，跳过校验。");
            return true; // 空条件视为通过
        }

        // 如果 involvedColumns 为空，但条件非空，尝试从条件中解析列名（作为后备）
        // 这主要为了兼容可能在元数据中 `columns` 字段未正确填充的情况
        if ((involvedColumns == null || involvedColumns.isEmpty()) && condition.matches(".*\\b(\\w+)\\b.*") ){
            System.out.println("[WARN] CHECK 约束 '" + checkConstraint.getName() + "' 的列列表为空，尝试从条件 '" + condition + "' 中动态解析列。");
            java.util.regex.Pattern dynamicColPattern = java.util.regex.Pattern.compile("\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b"); // 匹配潜在的列名
            java.util.regex.Matcher dynamicColMatcher = dynamicColPattern.matcher(condition);
            List<String> dynamicallyParsedCols = new ArrayList<>();
            while(dynamicColMatcher.find()){
                String potentialCol = dynamicColMatcher.group(1);
                // 检查它是否真的是一个列名（存在于 schemaList 中）
                boolean isActualColumn = false;
                for(String[] colDef : schemaList){
                    if(colDef[0].equalsIgnoreCase(potentialCol)){
                        isActualColumn = true;
                        break;
                    }
                }
                if(isActualColumn && !dynamicallyParsedCols.contains(potentialCol)) {
                     dynamicallyParsedCols.add(potentialCol);
                }
            }
            if (!dynamicallyParsedCols.isEmpty()) {
                System.out.println("[DEBUG] 从条件动态解析到的列: " + dynamicallyParsedCols);
                involvedColumns = dynamicallyParsedCols;
            } else {
                System.err.println("错误: CHECK 约束 '" + checkConstraint.getName() + "' 的列列表为空，且无法从条件 '"+condition+"' 中动态解析出有效的列名。校验失败。");
                return false;
            }
        }

        // 支持的模式: "columnName operator value" 或 "columnName operator columnName2" (暂不完整支持后者)
        // 简单比较: col > val, col = val, col != 'stringval'
        // 简单 BETWEEN: col BETWEEN val1 AND val2
        java.util.regex.Pattern simpleComparisonPattern = java.util.regex.Pattern.compile(
            "\\s*(\\w+)\\s*(>|>=|<|<=|=|!=|<>)\\s*('[^']*'|\\d+(?:\\.\\d+)?|true|false|\\bNULL\\b)\\s*",
            java.util.regex.Pattern.CASE_INSENSITIVE);
        java.util.regex.Matcher matcher = simpleComparisonPattern.matcher(condition);

        // TODO: 添加对 col BETWEEN val1 AND val2 的支持
        // Pattern betweenPattern = Pattern.compile("\\s*(\\w+)\\s+BETWEEN\\s+('[^']*'|\\d+)\\s+AND\\s+('[^']*'|\\d+)\\s*", Pattern.CASE_INSENSITIVE);

        if (matcher.matches()) {
            String columnName = matcher.group(1).trim();
            String operator = matcher.group(2).trim();
            String valueStr = matcher.group(3).trim();

            if (!involvedColumns.contains(columnName)) {
                 System.err.println("错误: CHECK 约束 '" + checkConstraint.getName() + "' 的条件 '" + condition + "' 中的列 '" + columnName + "' 未在约束声明的列列表 " + involvedColumns + " 中。校验失败。");
                 return false;
            }
            if (!columnIndexMap.containsKey(columnName)) {
                System.err.println("错误: CHECK 约束 '" + checkConstraint.getName() + "' 引用了表 '" + tableName +"' 中不存在的列: " + columnName + " (条件: "+condition+")");
                return false;
            }

            int colIndex = columnIndexMap.get(columnName);
            String actualValueStr = processedData.get(colIndex);

            String columnType = "";
            for(String[] def : schemaList){
                if(def[0].equals(columnName)) {
                    columnType = def[1].toUpperCase();
                    break;
                }
            }
            if (columnType.isEmpty()){
                 System.err.println("错误: 无法确定 CHECK 约束中列 '" + columnName + "' 的数据类型。校验失败。");
                 return false;
            }

            try {
                return evaluateCondition(actualValueStr, operator, valueStr, columnType, checkConstraint.getName());
            } catch (NumberFormatException e) {
                System.err.println("错误: 评估 CHECK 约束 '" + checkConstraint.getName() + "' 时数值转换失败: " + e.getMessage() + " (条件: "+condition+")");
                return false;
            } catch (IllegalArgumentException e) {
                System.err.println("错误: 评估 CHECK 约束 '" + checkConstraint.getName() + "' 时发生错误: " + e.getMessage() + " (条件: "+condition+")");
                return false;
            }
        } else {
            System.err.println("警告: CHECK 约束 '"+checkConstraint.getName()+"' 的条件格式 '" + condition + "' 目前不完全支持或解析失败。此约束校验跳过 (视为通过)。");
            return true; // 暂不支持的格式，暂时放行，后续应增强解析能力或返回false
        }
    }

    private static boolean evaluateCondition(String actualValueStr, String operator, String expectedValueStr, String columnType, String constraintName) {
        boolean actualIsNull = actualValueStr.isEmpty(); // processedData 中空字符串代表 NULL
        boolean expectedIsLiteralNull = expectedValueStr.equalsIgnoreCase("NULL");

        // 1. 处理与 SQL NULL 的比较
        if (expectedIsLiteralNull) { // column IS NULL, column IS NOT NULL
            if (operator.equals("=")) return actualIsNull;
            if (operator.equals("!=") || operator.equals("<>")) return !actualIsNull;
            // 对于其他操作符 (>, <, >=, <=) 与 NULL 的比较，SQL标准结果是 UNKNOWN (视为false)
            System.out.println("[DEBUG] CHECK '"+constraintName+"': Comparing with NULL using operator '"+operator+"'. Actual is null: "+actualIsNull+". Result: false.");
            return false;
        }

        // 2. 如果实际值为 NULL，但期望值不是 NULL 字面量，则大多数比较都为 false
        if (actualIsNull && !expectedIsLiteralNull) {
            // 只有 IS NOT NULL (已在上面通过 != NULL 处理) 会是 true。
            // 其他所有与NULL的比较 (col > 5, col = 'abc' when col is NULL) 结果为 false。
            System.out.println("[DEBUG] CHECK '"+constraintName+"': Actual value is NULL, expected is not NULL ('"+expectedValueStr+"'). Operator '"+operator+"'. Result: false.");
            return false;
        }

        // 3. 常规值比较 (此时 actualValueStr 不是空字符串了)
        String cleanExpectedValueStr = (expectedValueStr.startsWith("'") && expectedValueStr.endsWith("'")) ?
                                       expectedValueStr.substring(1, expectedValueStr.length() - 1) :
                                       expectedValueStr;
        try {
            switch (columnType) {
                case "INT": case "INTEGER":
                    long actualLong = Long.parseLong(actualValueStr);
                    long expectedLong = Long.parseLong(cleanExpectedValueStr);
                    switch (operator) {
                        case "=": return actualLong == expectedLong;
                        case "!=": case "<>": return actualLong != expectedLong;
                        case ">": return actualLong > expectedLong;
                        case ">=": return actualLong >= expectedLong;
                        case "<": return actualLong < expectedLong;
                        case "<=": return actualLong <= expectedLong;
                        default: throw new IllegalArgumentException("不支持的 INTEGER 比较运算符: " + operator);
                    }
                case "DECIMAL": case "NUMERIC": case "FLOAT": case "DOUBLE":
                    double actualDouble = Double.parseDouble(actualValueStr);
                    double expectedDouble = Double.parseDouble(cleanExpectedValueStr);
                    final double EPSILON = 1e-9; // 用于浮点数比较的容差
                    switch (operator) {
                        case "=": return Math.abs(actualDouble - expectedDouble) < EPSILON;
                        case "!=": case "<>": return Math.abs(actualDouble - expectedDouble) >= EPSILON;
                        case ">": return actualDouble > expectedDouble;
                        case ">=": return actualDouble >= expectedDouble - EPSILON; // actual >= expected
                        case "<": return actualDouble < expectedDouble;
                        case "<=": return actualDouble <= expectedDouble + EPSILON; // actual <= expected
                        default: throw new IllegalArgumentException("不支持的 DECIMAL/FLOAT 比较运算符: " + operator);
                    }
                case "VARCHAR": case "CHAR": case "TEXT":
                    int comparisonResult = actualValueStr.compareTo(cleanExpectedValueStr);
                    switch (operator) {
                        case "=": return comparisonResult == 0;
                        case "!=": case "<>": return comparisonResult != 0;
                        case ">": return comparisonResult > 0;
                        case ">=": return comparisonResult >= 0;
                        case "<": return comparisonResult < 0;
                        case "<=": return comparisonResult <= 0;
                        default: throw new IllegalArgumentException("不支持的字符串比较运算符: " + operator);
                    }
                case "BOOLEAN":
                    // processedData 中的布尔值已经是 "true" 或 "false"
                    boolean actualBool = Boolean.parseBoolean(actualValueStr);
                    boolean expectedBool;
                    if (cleanExpectedValueStr.equalsIgnoreCase("true") || cleanExpectedValueStr.equals("1")) expectedBool = true;
                    else if (cleanExpectedValueStr.equalsIgnoreCase("false") || cleanExpectedValueStr.equals("0")) expectedBool = false;
                    else throw new IllegalArgumentException("CHECK 约束中无效的布尔期望值: " + cleanExpectedValueStr);

                    switch (operator) {
                        case "=": return actualBool == expectedBool;
                        case "!=": case "<>": return actualBool != expectedBool;
                        default: throw new IllegalArgumentException("不支持的 BOOLEAN 比较运算符: " + operator + " (仅支持 = 和 !=)");
                    }
                case "DATE": case "TIMESTAMP": case "DATETIME": 
                    // 假设日期/时间戳已规范化为可直接字符串比较的格式 (YYYY-MM-DD HH:MM:SS)
                    int dtComparisonResult = actualValueStr.compareTo(cleanExpectedValueStr);
                    switch (operator) {
                        case "=": return dtComparisonResult == 0;
                        case "!=": case "<>": return dtComparisonResult != 0;
                        case ">": return dtComparisonResult > 0;
                        case ">=": return dtComparisonResult >= 0;
                        case "<": return dtComparisonResult < 0;
                        case "<=": return dtComparisonResult <= 0;
                        default: throw new IllegalArgumentException("不支持的 DATE/TIMESTAMP 比较运算符: " + operator);
                    }
                default:
                    System.err.println("警告: CHECK 约束 '"+constraintName+"' 作用于未知或不支持比较的类型 '" + columnType + ". 条件: " + actualValueStr + operator + cleanExpectedValueStr + ". 校验视为通过。");
                    return true; // 无法比较的类型，暂时放行
            }
        } catch (NumberFormatException nfe) {
            System.err.println("警告: CHECK 约束 '"+constraintName+"' 在进行类型转换为数值时失败。实际值='" + actualValueStr + "', 期望值='" + cleanExpectedValueStr + "', 列类型='" + columnType + "'. 错误: " + nfe.getMessage() + ". 校验视为失败。");
            return false; // 类型转换失败意味着条件无法满足
        }
    }

    // +++ 新增 FOREIGN KEY 校验方法 +++
    private static boolean validateForeignKeyConstraint(DB db, // Current transaction's DB instance
                                                    TableConstraint fkConstraint,
                                                    Map<String, String> currentRowValues, // Column name -> value for the row being inserted/updated in child table
                                                    List<String[]> childSchemaList, // Schema of the child table (used for context, not directly for fkValues here)
                                                    String childTableName,
                                                    String dbName) { // Current database name

        String parentTableName = fkConstraint.getReferencedTable();
        List<String> fkColumnsInChild = fkConstraint.getColumns(); // Columns in child table that form the FK
        List<String> referencedColsInParent = fkConstraint.getReferencedColumns(); // Columns in parent table that are referenced

        if (parentTableName == null || fkColumnsInChild == null || referencedColsInParent == null ||
                fkColumnsInChild.isEmpty() || referencedColsInParent.isEmpty() || fkColumnsInChild.size() != referencedColsInParent.size()) {
            System.err.println("错误: FOREIGN KEY 约束 '" + fkConstraint.getName() + "' on table '" + childTableName + "' 定义不完整，跳过校验。");
            return true; // Definition is malformed, bypass to prevent false negatives during development. Consider false for production.
        }

        // 1. Extract values for FK columns from the current row being inserted/updated in the child table.
        List<String> fkValuesFromChildRow = new ArrayList<>();
        boolean anyFkPartOfChildIsNull = false;
        for (String fkColName : fkColumnsInChild) {
            String fkValue = currentRowValues.get(fkColName); // Get value using name from processedData map
            if (fkValue == null || fkValue.isEmpty()) { // Empty string from processedData means NULL
                fkValuesFromChildRow.add(null); // Store actual null for logic
                anyFkPartOfChildIsNull = true;
            } else {
                fkValuesFromChildRow.add(fkValue);
            }
        }

        // SQL standard (MATCH SIMPLE behavior): If any part of a composite foreign key in the child is NULL, the constraint is satisfied.
        if (anyFkPartOfChildIsNull) {
            System.out.println("[DEBUG] FK Check for '" + fkConstraint.getName() + "' on table '"+ childTableName +"' : At least one FK column value in child is NULL. Constraint is satisfied.");
            return true;
        }
        // If we reach here, all parts of the FK in the child row are non-NULL.

        // 2. Get parent table's column information (metadata)
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> parentTableColumnsMeta = (List<Map<String, Object>>) db
            .hashMap("columns_" + parentTableName)
            .keySerializer(Serializer.STRING)
            .valueSerializer(Serializer.JAVA)
            .createOrOpen()
            .get("metadata"); // Expect parent table schema to exist

        if (parentTableColumnsMeta == null || parentTableColumnsMeta.isEmpty()) {
            System.err.println("错误: 无法获取 FOREIGN KEY 约束 '" + fkConstraint.getName() + "' 引用的父表 '" + parentTableName + "' 的列元数据。父表可能不存在或无列信息。");
            return false; // Cannot validate if parent schema is missing
        }

        Map<String, Integer> parentColNameToIndexMap = new HashMap<>();
        for (int i = 0; i < parentTableColumnsMeta.size(); i++) {
            Map<String, Object> colMeta = parentTableColumnsMeta.get(i);
            String colName = (String) colMeta.get("name");
            if (colName != null) {
                parentColNameToIndexMap.put(colName.toLowerCase(), i); // Use lowercase for matching
            }
        }

        // Map referenced column names (from parent) to their actual indices in parent's data rows
        List<Integer> parentReferencedColIndices = new ArrayList<>();
        for (String refColNameInParent : referencedColsInParent) {
            Integer idx = parentColNameToIndexMap.get(refColNameInParent.toLowerCase());
            if (idx == null) {
                System.err.println("错误: FOREIGN KEY 约束 '" + fkConstraint.getName() +
                                   "' 引用的父表 '" + parentTableName + "' 中的列 '" + refColNameInParent + "' 未找到于父表元数据中。");
                return false; // Referenced column in parent doesn't exist
            }
            parentReferencedColIndices.add(idx);
        }

        // 3. Read data from the parent table to check for matching rows.
        ConcurrentMap<Long, Object> parentTableDataMap = systemDBEngine.getDataStorage(db, parentTableName);
        if (parentTableDataMap == null) { // This means parent table has no data storage map (might be empty or not exist in data files)
            System.out.println("[DEBUG] FK Check for '" + fkConstraint.getName() + "': Referenced parent table '" + parentTableName + "' has no data map. FK violation as child FK values are non-NULL.");
            return false; // If child FK is non-NULL, it cannot match anything in an empty/non-existent parent data map.
        }

        boolean matchFoundInParent = false;
        for (Object parentRowStoreObject : parentTableDataMap.values()) {
            // 使用安全的类型转换处理父表数据
            List<String> parentRowActualData = null;
            
            // 标准化的数据行提取（新格式: [seq, [data_list]] 或旧格式: [data_list]）
            if (parentRowStoreObject instanceof List<?> && ((List<?>)parentRowStoreObject).size() > 1 && ((List<?>)parentRowStoreObject).get(1) instanceof List<?>) {
                Object listData = ((List<?>)parentRowStoreObject).get(1);
                @SuppressWarnings("unchecked")
                List<Object> originalRow = (List<Object>)listData;
                // 确保所有值都安全转换为String
                List<String> convertedRow = new ArrayList<>();
                for (Object item : originalRow) {
                    convertedRow.add(item != null ? String.valueOf(item) : "");
                }
                parentRowActualData = convertedRow;
            } else if (parentRowStoreObject instanceof List<?>) {
                try {
                    @SuppressWarnings("unchecked")
                    List<Object> originalRow = (List<Object>)parentRowStoreObject;
                    // 确保所有值都安全转换为String
                    List<String> convertedRow = new ArrayList<>();
                    for (Object item : originalRow) {
                        convertedRow.add(item != null ? String.valueOf(item) : "");
                    }
                    parentRowActualData = convertedRow;
                } catch (ClassCastException e) {
                    System.err.println("[WARN] Skipping non-standard row format in parent table '" + parentTableName + "' during FK check: " + parentRowStoreObject);
                    continue;
                }
            } else {
                System.err.println("[WARN] Skipping unknown row format in parent table '" + parentTableName + "' during FK check: " + parentRowStoreObject);
                continue;
            }

            if (parentRowActualData == null) {
                continue; // 如果无法解析父行数据，跳过此行
            }

            boolean currentRowInParentMatches = true;
            for (int i = 0; i < fkValuesFromChildRow.size(); i++) {
                String childFkValue = fkValuesFromChildRow.get(i); // This is non-NULL here
                int parentColIdxToCompare = parentReferencedColIndices.get(i);

                if (parentColIdxToCompare >= parentRowActualData.size()) { // Parent row is shorter than expected (data corruption?)
                    currentRowInParentMatches = false;
                    System.err.println("[WARN] FK Check: Parent row in '" + parentTableName + "' is too short to access referenced column index " + parentColIdxToCompare + ". Row: " + parentRowActualData);
                    break;
                }
                String parentReferencedColValue = parentRowActualData.get(parentColIdxToCompare);

                // If parent's value is effectively NULL (empty string), it cannot match a non-NULL child FK value.
                if (parentReferencedColValue == null || parentReferencedColValue.isEmpty()) {
                    currentRowInParentMatches = false;
                    break;
                }
                // Direct string comparison. Assumes data types are compatible or already stringified appropriately.
                if (!parentReferencedColValue.equals(childFkValue)) {
                    currentRowInParentMatches = false;
                    break;
                }
            }

            if (currentRowInParentMatches) {
                matchFoundInParent = true;
                break; // Found a matching row in parent table
            }
        }

        if (!matchFoundInParent) {
            System.out.println("[INFO] FOREIGN KEY VIOLATION for constraint '" + fkConstraint.getName() +
                               "' on table '" + childTableName + "'. Values " + fkValuesFromChildRow +
                               " for columns [" + String.join(",", fkColumnsInChild) + "] not found in referenced columns [" +
                               String.join(",", referencedColsInParent) + "] of table '" + parentTableName + "'.");
        }
        return matchFoundInParent;
    }

    /**
     * 获取表的描述信息，用于DESCRIBE TABLE命令。
     * @param dbName 数据库名称
     * @param tableName 表名
     * @return 表的结构信息列表，每行为一个字符串数组 [列名, 类型, 是否可为空, 默认值, 主键]
     *         如果表不存在或无法获取信息，则返回空列表或特定的错误指示。
     */
    @SuppressWarnings("unchecked")
    public static List<String[]> getTableDescription(String dbName, String tableName) {
        List<String[]> description = new ArrayList<>();
        TransactionLogger txLogger = TransactionLogger.getInstance();

        if (!txLogger.isTransactionActive()) {
            System.err.println("错误: getTableDescription 操作需要在活动的事务中执行。当前没有活动事务。 (数据库: " + dbName + ", 表: " + tableName + ")");
            // 返回一个特殊的错误行或抛出异常可能更好
            description.add(new String[]{"ERROR", "Operation must be within an active transaction.", "", "", ""});
            return description;
        }

        String activeTxDbName = txLogger.getTransactionDatabaseName();
        if (activeTxDbName == null || !activeTxDbName.equals(dbName)) {
            System.err.println("错误: getTableDescription 操作的数据库 '" + dbName + "' 与当前活动事务的数据库 '" +
                               (activeTxDbName == null ? "未知" : activeTxDbName) + "' 不符。 (表: " + tableName + ")");
            description.add(new String[]{"ERROR", "Database context mismatch.", "", "", ""});
            return description;
        }

        DB db = txLogger.getCurrentTransactionDB();
        if (db == null || db.isClosed()) {
            System.err.println("错误: getTableDescription 操作无法执行。与当前活动事务关联的数据库实例 ('" + dbName + "') 无效或已关闭。 (表: " + tableName + ")");
            description.add(new String[]{"ERROR", "Transaction DB instance is invalid or closed.", "", "", ""});
            return description;
        }

        try {
            // 检查表是否存在
            Map<String, Object> tableInfoMap = (Map<String, Object>) db
                .hashMap("TableInfo")
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("tables", new HashMap<String, Object>());

            List<String> tablesList = tableInfoMap != null ?
                (List<String>) tableInfoMap.getOrDefault("tablesList", new ArrayList<String>()) :
                new ArrayList<>();

            if (!tablesList.contains(tableName)) {
                System.err.println("❌ 表 [" + tableName + "] 在数据库 [" + dbName + "] 中不存在");
                description.add(new String[]{"ERROR", "Table " + tableName + " does not exist.", "", "", ""});
                return description;
            }

            // 获取列信息
            List<Map<String, Object>> columnsInfo = (List<Map<String, Object>>) db
                .hashMap("columns_" + tableName)
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .get("metadata"); // Assuming "metadata" key always exists if table exists

            if (columnsInfo == null || columnsInfo.isEmpty()) {
                System.err.println("❌ 表 [" + tableName + "] 结构信息不存在或为空");
                 description.add(new String[]{"ERROR", "Table " + tableName + " has no column information.", "", "", ""});
                return description;
            }

            // 获取约束信息，以确定主键
            List<String> primaryKeyColumns = new ArrayList<>();
            // 新增：收集其他约束类型信息
            Map<String, List<String>> uniqueColumns = new HashMap<>(); // 存储列名 -> 所属的唯一约束名称列表
            Map<String, Map<String, List<String>>> foreignKeyColumns = new HashMap<>(); // 存储列名 -> (约束名称 -> 引用表和列)
            Map<String, List<String>> checkColumns = new HashMap<>(); // 存储列名 -> 相关CHECK约束描述列表
            
            List<Map<String, Object>> constraintsMapList = (List<Map<String, Object>>) db
                .hashMap("constraints_" + tableName)
                .keySerializer(Serializer.STRING)
                .valueSerializer(Serializer.JAVA)
                .createOrOpen()
                .getOrDefault("metadata", new ArrayList<Map<String, Object>>());

            for (Map<String, Object> constraintMap : constraintsMapList) {
                TableConstraint constraint = TableConstraint.fromMap(constraintMap);
                
                // 根据约束类型处理
                switch(constraint.getType()) {
                    case PRIMARY_KEY:
                        primaryKeyColumns.addAll(constraint.getColumns());
                        break;
                        
                    case UNIQUE:
                        // 为每个受约束列添加唯一约束信息
                        for(String col : constraint.getColumns()) {
                            uniqueColumns.computeIfAbsent(col, k -> new ArrayList<>()).add(constraint.getName());
                        }
                        break;
                        
                    case FOREIGN_KEY:
                        // 为每个外键约束列添加引用信息
                        String refTableAndCols = constraint.getReferencedTable() + "(" + 
                            String.join(",", constraint.getReferencedColumns()) + ")";
                        for(String col : constraint.getColumns()) {
                            foreignKeyColumns.computeIfAbsent(col, k -> new HashMap<>())
                                .put(constraint.getName(), List.of(refTableAndCols));
                        }
                        break;
                        
                    case CHECK:
                        // 为每个CHECK约束相关列添加条件信息
                        String checkInfo = constraint.getName() + ": " + constraint.getCheckCondition();
                        for(String col : constraint.getColumns()) {
                            checkColumns.computeIfAbsent(col, k -> new ArrayList<>()).add(checkInfo);
                        }
                        break;
                        
                    case NOT_NULL: 
                        // NOT_NULL约束已通过nullable标志处理，此处无需额外操作
                        break;
                }
            }

            // 格式化输出
            for (Map<String, Object> colInfo : columnsInfo) {
                String colName = (String) colInfo.get("name");
                String colType = (String) colInfo.get("type");
                Integer length = (Integer) colInfo.get("length");
                Boolean nullable = (Boolean) colInfo.get("nullable");

                String typeWithLength = colType;
                if (length != null && length > 0) {
                    typeWithLength += "(" + length + ")";
                }

                String nullableStr = (nullable != null && nullable) ? "是" : "否";
                String defaultValue = "N/A"; // 默认值信息当前未存储
                String isPrimaryKey = primaryKeyColumns.contains(colName) ? "是" : "否";
                
                // 添加其他约束信息
                String uniqueStr = uniqueColumns.containsKey(colName) ? 
                    String.join(", ", uniqueColumns.get(colName)) : "否";
                
                String foreignKeyStr = "否";
                if (foreignKeyColumns.containsKey(colName)) {
                    foreignKeyStr = foreignKeyColumns.get(colName).entrySet().stream()
                        .map(e -> {
                            String refInfo = e.getKey() + "->";
                            if (!e.getValue().isEmpty()) {
                                refInfo += e.getValue().get(0);
                            }
                            return refInfo;
                        })
                        .collect(Collectors.joining("; "));
                }
                
                String checkStr = checkColumns.containsKey(colName) ?
                    String.join("; ", checkColumns.get(colName)) : "否";

                // 将所有信息组合成一行
                description.add(new String[]{
                    colName, typeWithLength, nullableStr, defaultValue, isPrimaryKey,
                    uniqueStr, foreignKeyStr, checkStr
                });
            }

        } catch (Exception e) {
            System.err.println("❌ 获取表 [" + tableName + "] 描述失败: " + e.getMessage());
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            System.err.println("堆栈跟踪:\n" + sw.toString().replace("\t", "    "));
            description.clear(); // Clear partial results on error
            description.add(new String[]{"ERROR", "Failed to get table description: " + e.getMessage(), "", "", ""});
        }
        return description;
    }
}
